package com.sunshine.ssm.realm;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.sunshine.ssm.entity.UserInfo;
import com.sunshine.ssm.service.IUserInfoService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by WeiHong on 2016/12/6.
 */
public class SsmRealm extends AuthorizingRealm {

    private static final Logger LOGGER = LoggerFactory.getLogger(SsmRealm.class);

    @Resource
    private IUserInfoService service;

    /**
     * 为当限前登录的用户授予角色和权
     *`1
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();
        if (username.equals("weihong")) {
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            authorizationInfo.addRole("user1");
            authorizationInfo.addStringPermission("add");
            return authorizationInfo;
        }
        return null;
    }

    /**
     * 验证当前登录用户
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获得当前登录人信息
        String userName = (String) authenticationToken.getPrincipal();
        //获得当前登录人信息
        String password = new String((char[]) authenticationToken.getCredentials());
        UserInfo info = new UserInfo();
        info.setUserName(userName);
        info.setPassword(password);
        try {
            EntityWrapper<UserInfo> wrapper = new EntityWrapper<>();
            wrapper.setEntity(info);
            List<UserInfo> userInfos = service.selectList(wrapper);
            if (userInfos != null && userInfos.size() > 0) {
                UserInfo userInfo = userInfos.get(0);
                return new SimpleAuthenticationInfo("dd", userInfo.getPassword(), getName());
            }
        } catch (Exception e) {
            LOGGER.error("用户登录失败！", e);
        }
        return null;
    }

    @Override
    protected void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        Cache c = getAuthenticationCache();
        LOGGER.debug("清除【认证】缓存之前");
        for (Object o : c.keys()) {
            LOGGER.info("认证缓存情况："+ o + " , " + c.get(o));
        }
        super.clearCachedAuthenticationInfo(principals);
        LOGGER.debug("调用父类清除【认证】缓存之后");
        for (Object o : c.keys()) {
            LOGGER.debug("认证缓存情况：" + o + " , " + c.get(o));
        }

        // 添加下面的代码清空【认证】的缓存

        String username = (String) principals.getPrimaryPrincipal();
        SimplePrincipalCollection spc = new SimplePrincipalCollection(username, getName());
        super.clearCachedAuthenticationInfo(spc);
        LOGGER.debug("添加了代码清除【认证】缓存之后");
        int cacheSize = c.keys().size();
        LOGGER.debug("【认证】缓存的大小:" + c.keys().size());
        if (cacheSize == 0) {
            LOGGER.debug("说明【认证】缓存被清空了。");
        }
    }

    @Override
    protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        LOGGER.debug("清除【授权】缓存之前");
        Cache c = getAuthorizationCache();
        for (Object o : c.keys()) {
            LOGGER.debug(o + " , " + c.get(o));
        }
        super.clearCachedAuthorizationInfo(principals);
        LOGGER.debug("清除【授权】缓存之后");
        int cacheSize = c.keys().size();
        LOGGER.debug("【授权】缓存的大小:" + cacheSize);

        for (Object o : c.keys()) {
            LOGGER.debug(o + " , " + c.get(o));
        }
        if (cacheSize == 0) {
            LOGGER.debug("说明【授权】缓存被清空了。");
        }

    }
}

